package com.maodou.core.base

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

/**
 * ViewModel 基类
 * 提供通用的状态管理和事件处理能力
 * 
 * @param TUiState UI 状态类型
 * @param TUiEvent UI 事件类型
 */
abstract class BaseViewModel<TUiState : Any, TUiEvent : Any> : ViewModel() {
    
    // 内部可变状态
    private val _uiState = MutableStateFlow(createInitialState())
    // 对外暴露的只读状态
    val uiState: StateFlow<TUiState> = _uiState.asStateFlow()
    
    // 内部可变事件流
    private val _uiEvent = MutableSharedFlow<TUiEvent>()
    // 对外暴露的只读事件流
    val uiEvent: SharedFlow<TUiEvent> = _uiEvent.asSharedFlow()
    
    /**
     * 创建初始状态
     * 子类必须实现此方法来提供初始的 UI 状态
     */
    protected abstract fun createInitialState(): TUiState
    
    /**
     * 更新 UI 状态
     * @param newState 新的状态
     */
    protected fun updateUiState(newState: TUiState) {
        _uiState.value = newState
    }
    
    /**
     * 更新 UI 状态（通过 lambda 函数）
     * @param update 状态更新函数
     */
    protected fun updateUiState(update: (TUiState) -> TUiState) {
        _uiState.value = update(_uiState.value)
    }
    
    /**
     * 发送 UI 事件
     * @param event 要发送的事件
     */
    protected fun emitUiEvent(event: TUiEvent) {
        viewModelScope.launch {
            _uiEvent.emit(event)
        }
    }
    
    /**
     * 获取当前 UI 状态
     * @return 当前状态
     */
    protected fun getCurrentUiState(): TUiState = _uiState.value
    
    /**
     * 处理加载状态的通用方法
     * 子类可以重写此方法来自定义加载状态的处理
     */
    protected open fun setLoading(isLoading: Boolean) {
        // 默认实现为空，子类可以根据需要重写
    }
    
    /**
     * 处理错误的通用方法
     * 子类可以重写此方法来自定义错误处理
     */
    protected open fun handleError(error: Throwable) {
        // 默认实现为空，子类可以根据需要重写
    }

}